<?php
declare(strict_types=1);

namespace App\Service;

use App\Utils\CustomUtils;
use Hyperf\Di\Annotation\Inject;
use App\Model\Dao\SysNodeDao;
use App\Exception\XZXValidationException;
use App\Constants\XZXResponseCode;
use Hyperf\Utils\ApplicationContext;
use Hyperf\Utils\Coroutine;
use App\Utils\DateUtils;
use Cassandra\Type\Custom;
use App\Utils\Tree;

class SysNodeService
{
    /**
     * @Inject()
     * @var SysNodeDao
     */
    private $SysNodeDao;

    public function get($param)
    {
        $result = $this->SysNodeDao->get($param['id']);
        if (!$result) {
            throw new XZXValidationException(XZXResponseCode::getMessage(XZXResponseCode::DATA_NOT_FOUND));
        }
        $param['parentId'] = $param['id'];
        $child_node_result = $this->SysNodeDao->getList($param, null, null);
        $result['childNodeList'] = $child_node_result;

        if(isset($result['createTime'])){
            $result['createTime'] = DateUtils::getDateTime($result['createTime']);
        }


        return CustomUtils::xeServiceReturnData(XZXResponseCode::SUCCESS_CODE,XZXResponseCode::getMessage(XZXResponseCode::SUCCESS_CODE),$result);
    }

    public function del($param)
    {
        $result = $this->SysNodeDao->get($param['id']);
        
        if (!$result) {
            throw new XZXValidationException(XZXResponseCode::getMessage(XZXResponseCode::DATA_NOT_FOUND));
        }

        $info = $this->get($param)['data'];
        
        if (! empty($info['childNodeList'])) {          
            throw new XZXValidationException('含有子节点,请将子节点删除后重试');
        }
        
        try {
            $result = $this->SysNodeDao->del($param['id'],false);
            
        } catch (\Throwable $th) {
            throw new XZXValidationException(XZXResponseCode::getMessage(XZXResponseCode::DEL_FAIL));
        }
        return CustomUtils::xeServiceReturnData(XZXResponseCode::SUCCESS_CODE,XZXResponseCode::getMessage(XZXResponseCode::SUCCESS_CODE),CustomUtils::xzxEmptyObject());
    }

    public function add($param)
    {
        // TODO: Implement add() method.
        //$data            =  [
        //    'name'       => $param['name'],
        //    'desciption' => $param['desciption'],
        //
        //];
        $data = $param;
        $data['id'] = CustomUtils::createUUID();
        $data['createTime'] = time(); 
        CustomUtils::xzxDebug($data);
        
        try {
            $this->SysNodeDao->insert($data);
        } catch (\Throwable $th) {
            throw new XZXValidationException(XZXResponseCode::getMessage(XZXResponseCode::ADD_FAIL));
        }
        return CustomUtils::xeServiceReturnData(XZXResponseCode::SUCCESS_CODE,XZXResponseCode::getMessage(XZXResponseCode::SUCCESS_CODE),CustomUtils::xzxEmptyObject());
    }

    public function edit($param)
    {
        $info = $this->SysNodeDao->get($param['id']);
        if (!$info) {
            throw new XZXValidationException(XZXResponseCode::getMessage(XZXResponseCode::DATA_NOT_FOUND));
        }

        $id = $param['id'];
        $data = array();
        
        
        foreach($param as $k => $v){
            if($k == "id"){
                continue;
            }            
            if(isset($v)){
                $data[$k] = $v;
            }
        }
        CustomUtils::xzxDebug($data);

        try {
            $this->SysNodeDao->update($id, $data);
        } catch (\Throwable $th) {
            throw new XZXValidationException(XZXResponseCode::getMessage(XZXResponseCode::EDIT_FAIL));
        }
        return CustomUtils::xeServiceReturnData(XZXResponseCode::SUCCESS_CODE,XZXResponseCode::getMessage(XZXResponseCode::SUCCESS_CODE),CustomUtils::xzxEmptyObject());
    }

    public function list(array $param)
    {

        $limit = $param['limit'];
        $page = $param['page']; 

        $total = $this->SysNodeDao->getCount($param);
        $list = $this->SysNodeDao->getList($param, $page, $limit);

        CustomUtils::xzxDebug($list);
        foreach ($list as $k => $v) {
            CustomUtils::xzxDebug($v);
            if(isset($v['createTime'])){
                $v['createTime'] = DateUtils::getDateTime($v['createTime']);
            }
            $list[$k] = $v;
        }

        $data = array(
            'total' => $total,
            'list' => $list
        );

        return CustomUtils::xeServiceReturnData(XZXResponseCode::SUCCESS_CODE,XZXResponseCode::getMessage(XZXResponseCode::SUCCESS_CODE),$data);
    }  
    
    // 根据父节点查找子节点
    public function getNodeOptions ($param) {

        $list = $this->SysNodeDao->getList($param);

        foreach ($list as $k => $v) {

            $item = [];

            $item['label'] = $v['title'];
            $item['value'] = $v['id'];

            $item['id'] = $v['id'];
            $item['parentId'] = $v['parentId'];

            $list[$k] = $item;
        }

        $tree = new Tree();
        $tree->init($list);
        $result = $tree->getTreeArray('root');

        $data = [
            'tree' => $result,
        ];

        return CustomUtils::xeServiceReturnData(XZXResponseCode::SUCCESS_CODE,XZXResponseCode::getMessage(XZXResponseCode::SUCCESS_CODE),$data);
    }

    // 菜单树形结构
    public function getNodeTree() {
        $result = $this->SysNodeDao->getList(['showStatus' => 1]);
        $tree = new Tree();
        $tree->init($result);
        $result = $tree->getTreeArray('root');
        return CustomUtils::xeServiceReturnData(XZXResponseCode::SUCCESS_CODE,XZXResponseCode::getMessage(XZXResponseCode::SUCCESS_CODE),$result);
    }

    public function getButtonNodeTree() {
        // 子菜单
        $nodes = $this->SysNodeDao->getList(['showStatus' => 0]);
        // 上级
        $parents = $this->SysNodeDao->getButtonNodeParents();
        $data = [];
        foreach ($parents as $key => $value) {
            $tmp = [
                'id'        => $value['id'],
                'parentId'  => $value['parentId'],
                'title'     => $value['title'],
                'children'  => [],
                '_level'    => 1
            ];
            foreach ($nodes as $k => $v) {
                if ($v['parentId'] == $value['id']) {
                    array_push($tmp['children'], [
                        'id'        => $v['id'],
                        'parentId'  => $v['parentId'],
                        'title'     => $v['title'],
                        '_level'    => 2
                    ]);
                }
            }
            array_push($data, $tmp);
        }
        
        return CustomUtils::xeServiceReturnData(XZXResponseCode::SUCCESS_CODE,XZXResponseCode::getMessage(XZXResponseCode::SUCCESS_CODE),$data);
    }

    public function checkRole($url, $roleId){
        $check = $this->SysNodeDao->checkRole($roleId, $url);
        if(!$check)
        {
            return false;
        }
        return true;
    }

    /**
     * 检查是否存在指定路由节点
     *
     * @param string $url 接口路由
     *
     * @return bool
     */
    public function hasUrlNode ($url) {

        $node = $this->SysNodeDao->getWhere([
            "status" => 1,
            "url" => $url,
        ]);

        return !!$node;
    }
}